package cz.semjob.document.processing.reader;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cz.semjob.common.util.TextUtil;
import cz.semjob.document.processing.DocumentInstance;
import cz.semjob.document.processing.DocumentProcessingException;
import cz.semjob.document.processing.DocumentSentence;
import cz.semjob.document.processing.DocumentWord;
import cz.semjob.linguistic.data.LinguisticSentence;
import cz.semjob.linguistic.data.LinguisticWord;
import cz.semjob.linguistic.reader.ILinguisticReader;
import cz.semjob.linguistic.reader.LanguageConfig;
import cz.semjob.linguistic.reader.LinguisticFormatProcessingException;

@Component
public class DocumentInstanceReader {
	
	public static final String PARAGRAPH_REGEXP ="(\r\n([ \\t]*)\r\n)|(\r([ \\t]*)\r)|(\n([ \\t]*)\n)";
	
	private ILinguisticReader linguisticReader;
	
	@Autowired
	private LanguageConfig languageConfig;
	
	
	@Autowired
	public DocumentInstanceReader(ILinguisticReader linguisticReader) {
		super();
		this.linguisticReader = linguisticReader;
	}

	public DocumentInstance readDocumentInstance(File documentFile, File linguisticProcessedFile) throws IOException, DocumentProcessingException{
		
		List<LinguisticSentence> linguisticSentences;
		try {
			linguisticSentences = linguisticReader.readDocument(linguisticProcessedFile);
		} catch (LinguisticFormatProcessingException e) {
			e.printStackTrace();
			throw new DocumentProcessingException(e);
		}
		
		String documentText = FileUtils.readFileToString(documentFile);
		
		DocumentInstance documentInstance = new DocumentInstance(documentText, languageConfig, documentFile.getAbsolutePath());
		fillDocumentInstance(documentInstance, linguisticSentences);
		
		return documentInstance;
	}
	
	private void fillDocumentInstance(DocumentInstance instance, List<LinguisticSentence> linguisticSentences) throws DocumentProcessingException {
		
		String documentText = instance.getText();
		int actualIndex = 0;
		int paragraphIndex = 0;
		int paragraphStart = 0;
		int previousSentenceEndIndex = 0;
		
		for (LinguisticSentence linguisticSentence : linguisticSentences) {
			DocumentSentence documentSentence = new DocumentSentence(instance);
			for (LinguisticWord linguisticWord : linguisticSentence.getWords()) {
				DocumentWord word = new DocumentWord(linguisticWord, documentSentence);
				int startIndex = documentText.indexOf(word.getText(), actualIndex);
				if (startIndex <0) {
					throw new DocumentProcessingException("Error while creating document instance: Word '" + word.getText() + "' not found in the input document.");
				}
				word.setIndexes(startIndex, startIndex+word.getLength()); 
				actualIndex = startIndex+word.getLength();
				documentSentence.addWord(word);
			}
			int sentenceStartIndex = documentSentence.getStartIndex();
			int newParagraphs = TextUtil.countTextOccurences(documentText, PARAGRAPH_REGEXP, previousSentenceEndIndex, sentenceStartIndex);
			if (newParagraphs > 0) {
				paragraphStart = TextUtil.getLastOccurenceEndIndex(documentText, PARAGRAPH_REGEXP,previousSentenceEndIndex, sentenceStartIndex);
				
			}
			paragraphIndex += newParagraphs;
			documentSentence.setParagraphIndex(paragraphIndex);
			documentSentence.setParagraphStartIndex(paragraphStart);
			documentSentence.setText(documentText.substring(documentSentence.getStartIndex(), documentSentence.getEndIndex()));
			instance.addSentence(documentSentence);
			previousSentenceEndIndex = documentSentence.getEndIndex();
			
		}
		
	}

	public void setLanguageConfig(LanguageConfig languageConfig) {
		this.languageConfig = languageConfig;
	}
	
	

}
